package com.example.myspringboot.type.handler;

import com.example.myspringboot.enums.ConfigTag;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author cy
 * @date 2024/6/18
 * ConfigTypeHandler 类处理 ConfigTag 类型的值与数据库 VARCHAR 类型之间的映射。
 * 它是一个自定义类型转换器，用于在 MyBatis 中处理特定类型的数据库操作。
 */
@MappedTypes(ConfigTag.class)
@MappedJdbcTypes(org.apache.ibatis.type.JdbcType.VARCHAR)
public class ConfigTypeHandler extends BaseTypeHandler<String> {

    /**
     * 将 Java 对象设置为 JDBC 准备语句的参数。
     * 此方法特定于 ConfigTag 类型的处理，但当前实现为空。
     *
     * @param ps        PreparedStatement，用于设置参数
     * @param i         参数索引
     * @param parameter 需要设置的参数对象
     * @param jdbcType  参数的 JDBC 类型
     * @throws SQLException 如果设置参数时发生错误
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 空实现，待后续添加具体逻辑
    }

    /**
     * 从ResultSet中获取一个可能为null的结果值。
     * 此方法旨在处理从数据库查询结果中获取特定列的值，该列可能为空。如果列值不为空，
     * 则将其转换为ConfigTag枚举类型，并返回对应的值；如果列值为空，则直接返回null。
     *
     * @param rs ResultSet对象，从中读取数据。
     * @param columnName 需要读取的列的名称。
     * @return 列中的字符串值，如果值为null或无法转换为ConfigTag，则返回null。
     * @throws SQLException 如果在处理ResultSet时发生错误。
     */
    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        // 从ResultSet中尝试获取列值。
        String code = rs.getString(columnName);

        // 尝试将获取的字符串值转换为ConfigTag枚举类型。
        ConfigTag configTag = ConfigTag.fromCode(code);

        // 如果转换成功，则返回ConfigTag的值；否则（即转换失败或原始值为null），返回null。
        return configTag != null ? configTag.getVal() : null;
    }


    /**
     * 从 ResultSet 中获取一个可能为 null 的结果值。
     * 此方法特定于从 ResultSet 的指定列索引中读取 ConfigTag 类型的值，但当前实现始终返回 null。
     *
     * @param rs          ResultSet，从中读取数据
     * @param columnIndex 列的索引
     * @return 列中的字符串值，如果值为 null，则返回 null
     * @throws SQLException 如果读取数据时发生错误
     */
    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }

    /**
     * 从 CallableStatement 中获取一个可能为 null 的结果值。
     * 此方法特定于从 CallableStatement 的指定列索引中读取 ConfigTag 类型的值，但当前实现始终返回 null。
     *
     * @param cs          CallableStatement，从中读取数据
     * @param columnIndex 列的索引
     * @return 列中的字符串值，如果值为 null，则返回 null
     * @throws SQLException 如果读取数据时发生错误
     */
    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }
}
